package org.cholm.drtest.proxy;

import java.io.PrintStream;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;


public class MediaMetaData {
	public static final String KEY_ALBUM_ARTIST = "albumArtist"; //String key: Album artist.
	public static final String KEY_ALBUM_TITLE = "album"; //String key: Album title.
	public static final String KEY_ARTIST = "artist"; //String key: Artist.
	public static final String KEY_BROADCAST_DATE = "broadcast"; //String key: Broadcast date.
	public static final String KEY_COMPOSER = "composer"; //String key: Composer.
	public static final String KEY_CREATION_DATE = "creation"; //String key: Creation date.
	public static final String KEY_DISC_NUMBER = "disc"; //Integer key: Disc number.
	public static final String KEY_EPISODE_NUMBER = "episode"; //Integer key: Episode number.
	public static final String KEY_HEIGHT = "height"; //Integer key: Height.
	public static final String KEY_LOCATION_LATITUDE = "latitude"; //Double key: Location latitude.
	public static final String KEY_LOCATION_LONGITUDE = "longitude"; //Double key: Location longitude.
	public static final String KEY_LOCATION_NAME = "location"; //String key: Location name.
	public static final String KEY_RELEASE_DATE = "release"; //String key: Release date.
	public static final String KEY_SEASON_NUMBER = "season"; //Integer key: Season number.
	public static final String KEY_SERIES_TITLE = "series"; //String key: Series title.
	public static final String KEY_STUDIO = "studio"; //String key: Studio.
	public static final String KEY_SUBTITLE = "subtitle"; //String key: Subtitle.
	public static final String KEY_TITLE = "title"; //String key: Title.
	public static final String KEY_TRACK_NUMBER = "track"; //Integer key: Track number.
	public static final String KEY_WIDTH = "width"; //Integer key: Width.
	public static final int MEDIA_TYPE_GENERIC = 0x0; //A media type representing generic media content.
	public static final int MEDIA_TYPE_MOVIE = 0x1; //A media type representing a movie.
	public static final int MEDIA_TYPE_MUSIC_TRACK = 0x3; //A media type representing a music track.
	public static final int MEDIA_TYPE_PHOTO = 0x4; //A media type representing a photo.
	public static final int MEDIA_TYPE_TV_SHOW = 0x2; //A media type representing an TV show.
	public static final int MEDIA_TYPE_USER = 0x64; //The smallest media type value that can be assigned for application-defined media types.

	/** Our media type */
	private int mediaType = MEDIA_TYPE_GENERIC;
	/** Map of keys to values */
	private Map<String,String> map = new HashMap<String,String>();
	/** List of images */
	private List<WebImage> images = new ArrayList<WebImage>();
	/**
	 * Constructor
	 */
	public MediaMetaData()
	{
	}
	/**
	 * Constructor with a type
	 *
	 * @param type
	 */
	public MediaMetaData(int type)
	{
		mediaType = type;
	}
	/**
	 * 	Adds an image to the list of images.
	 */
	public void addImage(WebImage image) { images.add(image); }
	/**
	 * 	Clears this object.
	 */
	public void clear() { map.clear(); images.clear(); }
	/**
	 * 	Clears the list of images.
	 */
	public void clearImages() { images.clear(); }
	/**
	 * 	Tests if the object contains a field with the given key.
	 */
	public boolean containsKey(String key) { return map.containsKey(key); }
	/**
	 * 	Compare to other
	 *
	 * @param other Other to compare to
	 *
	 * @return true of this and other are the same
	 */
	public boolean equals(Object other)
	{
		if (!(other instanceof MediaMetaData)) return false;
		MediaMetaData o = (MediaMetaData)other;
		return (this.mediaType == o.mediaType &&
				this.map.equals(o.map) &&
				this.images.equals(o.images));
	}
	/**
	 * Reads the value of a date field.
	 */
	public Calendar getDate (String key) {
		if (!containsKey(key)) return null;

		try {
			String s = (String)map.get(key);
			DateFormat df = new SimpleDateFormat();
			Date       dt = df.parse(s);
			Calendar   cl = Calendar.getInstance();
			cl.setTime(dt);
			return cl;
		} catch (ParseException e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 	Reads the value of a date field, as a string.
	 */
	public String getDateAsString(String key) {
		return getString(key);
	}
	/**
	 * 	Reads the value of a double field.
	 */
	public double getDouble(String key) {
		if (!containsKey(key)) return 0;
		return Double.parseDouble(map.get(key).toString());
	}
	/**
	 * 	Returns the list of images.
	 */
	public List<WebImage> getImages() { return images; }
	/**
	 * 	Reads the value of an int field.
	 */
	public int getInt(String key) {
		if (!containsKey(key)) return 0;
		return Integer.parseInt(map.get(key).toString());
	}
	/**
	 * 	Gets the media type.
	 */
	public int getMediaType() { return mediaType; }
	/**
	 * 	Reads the value of a String field.
	 */
	public String getString(String key) {
		if (!containsKey(key)) return "";
		return (String)map.get(key);
	}
	/**
	 * 	Checks if the metadata includes any images.
	 */
	public boolean hasImages() { return images.size() > 0; }
	/**
	 *
	 */
	public int hashCode() { return 0; }
	/**
	 * Returns a set of keys for all fields that are present in the object.
	 * @return set of keys
	 */
	public Set<String>	 keySet() { return map.keySet(); }
	/**
	 * 	Stores a value in a date field.
	 */
	public void putDate(String key, Calendar value) {
		map.put(key, value.toString());
	}
	/**
	 * 	Stores a value in a double field.
	 */
	public void putDouble(String key, double value) {
		map.put(key, String.valueOf(value));
	}
	/**
	 * 	Stores a value in an int field.
	 */
	public void putInt(String key, int value) {
		map.put(key, String.valueOf(value));
	}
	/**
	 * 	Stores a value in a String field.
	 */
	public void putString(String key, String value) {
		map.put(key, value);
	}
	public void print(String ind) {
		PrintStream out = System.out;
		out.print(ind);
		switch (mediaType) {
		case MEDIA_TYPE_GENERIC: out.println("Generic media content"); break;
		case MEDIA_TYPE_MOVIE: out.println("A movie"); break;
		case MEDIA_TYPE_MUSIC_TRACK: out.println("A music track"); break;
		case MEDIA_TYPE_PHOTO: out.println("A photo");break;
		case MEDIA_TYPE_TV_SHOW: out.println("A TV show"); break;
		default: out.println("User type # " + (mediaType-MEDIA_TYPE_USER)); break;
		}

		for (Map.Entry<String,String> entry : map.entrySet()) {
		    String key   = entry.getKey();
		    String value = entry.getValue();
		    out.printf("%s %10s: %s\n", ind, key, value);
		}
		if (!this.hasImages()) return;
		out.printf("%s Images:", ind);
		for (WebImage img : images) {
			out.printf("  %s %s", ind, img.toString());
		}
	}
}
// EOF
